<template>
  <edit-card
    :title="title"
    :confirm-text="'确定'"
    :type="type"
    :loading="pageLoading || updateLoading || addLoading || getDetailLoading"
    @confirm="submit"
  >
    <template #titleInfo>
      <div class="tip">
        <a-tooltip
          :title="'训练日志、资源监控等内容依托于算法代码，若算法不支持，则相关内容为空'"
          overlay-class-name="custom-overlay-className"
          :overlay-inner-style="{ width: '296px' }"
        >
          <i class="icon-information-fill iconfont"></i>
        </a-tooltip>
      </div>
    </template>
    <a-anchor
      style="position: absolute; top: 16px; right: 16px; width: 108px"
      :items="[
        { key: '1', href: '#components-anchor-demo-basic', title: '算法详情' },
        { key: '2', href: '#components-anchor-demo-static', title: '资源分配' }
      ]"
      wrapper-class="a-anchor-class"
      :target-offset="500"
      :offset-top="80 + 54"
      @click.prevent
    />
    <div id="components-anchor-demo-basic" class="default-class-title">算法详情</div>
    <a-form
      ref="mainFormRef"
      :colon="false"
      :model="mainForm"
      style="width: 824px"
      :rules="mainFormRules"
      name="mainForm"
      :label-align="'left'"
    >
      <a-form-item label="算法名称" name="name">
        <g-input v-model:value="mainForm.name" v-trim :search="false" class="w-440" placeholder="请输入算法名称" :maxlength="200" />
      </a-form-item>
      <a-form-item v-if="type === 'add'" label="算法类型" name="type">
        <a-select v-model:value="mainForm.type" placeholder="请选择算法类型" :options="ALGO_TYPE_OPTIONS" class="w-440" />
      </a-form-item>
      <a-form-item v-if="type === 'add'" label="镜像" name="imageId">
        <a-select
          v-model:value="mainForm.imageId"
          :options="imageList"
          placeholder="请选择镜像"
          :field-names="{ label: 'imageName', value: 'id' }"
          :get-popup-container="(triggerNode: any) => triggerNode.parentNode"
          class="w-440"
          @change="imageSelect"
        />
      </a-form-item>
      <a-form-item v-if="type === 'add'" label="算法框架" name="frame">
        <g-input v-trim :value="mainForm.frame" :search="false" disabled class="w-440" placeholder="" />
      </a-form-item>
      <a-form-item label="算法文件" name="fileUrl">
        <file-upload
          v-model:file-url="mainForm.fileUrl"
          class="file-upload w-440"
          :max-count="1"
          :is-preview="false"
          accept="zip"
          suffix="zip"
          :module-prefix="'algorithm'"
        >
          <a-button type="dashed" size="small" class="icon-with-btn btn-mini">
            <i class="iconfont icon-upload-line"></i>
            上传
          </a-button>
        </file-upload>
      </a-form-item>
      <a-form-item label="描述" name="remark">
        <a-textarea v-model:value="mainForm.remark" v-trim class="w-440 h-106" placeholder="请输入描述" :maxlength="200" show-count />
      </a-form-item>
    </a-form>
    <div id="components-anchor-demo-static" class="default-class-title mt-120">资源分配</div>

    <a-form ref="resourceRef" :model="resourceForm" :colon="false" :rules="resourceRules" name="resourceForm" :label-align="'left'">
      <a-form-item label="GPU" name="gpu">
        <a-select v-model:value="resourceForm.gpu" :options="GPU_OPTIONS" class="w-440" />
      </a-form-item>
      <a-form-item label="CPU" name="cpuMemory">
        <a-select v-model:value="resourceForm.cpuMemory" :options="CPU_OPTIONS" class="w-440" @change="cpuMemoryChange" />
      </a-form-item>
    </a-form>
  </edit-card>
</template>

<script lang="ts" setup>
  import { message } from 'ant-design-vue'
  import type { Rule } from 'ant-design-vue/es/form'
  import { SelectValue } from 'ant-design-vue/es/select'
  import { cloneDeep } from 'g6-fn'
  import { computed, ref } from 'vue'
  import { useRequest } from 'vue-request'
  import { useRoute, useRouter } from 'vue-router'

  import { algoDevApi, mirrorManageApi } from '@/services/api'
  import { validateBitLen, validateDirName } from '@/utils'

  import { ALGO_TYPE_OPTIONS, CPU_OPTIONS, GPU_OPTIONS } from '../../options'
  import { AlgoType } from '../types'
  const route = useRoute()
  const router = useRouter()
  const algoId = route.params.id as string | ''
  const type = ref((algoId ? 'edit' : 'add') as 'edit' | 'add')
  const detailData = ref<AlgoType>({})
  const title = computed(() => {
    return algoId ? `编辑算法（${detailData.value.name || ''}）` : '创建算法'
  })

  /* 算法详情表单 -------------------------------------------------------------------------- */
  interface MainForm {
    name: string
    imageId: number | undefined
    frame: string
    remark: string
    fileUrl: string
    type: number | undefined
  }
  let mainFormRef = ref()
  let mainForm = ref<MainForm>({
    name: '',
    type: undefined,
    fileUrl: '',
    imageId: undefined,
    frame: '',
    remark: ''
  })
  const mainFormRules: Record<string, Rule[]> = {
    name: [
      { required: true, trigger: 'change', message: '请输入算法名称' },
      { validator: validateDirName() },
      { validator: validateBitLen(200), trigger: 'change' }
    ],
    type: [{ required: true, message: '请选择算法类型' }],
    imageId: [{ required: true, message: '请选择镜像' }],
    frame: [{ required: true }]
  }
  // 获取镜像数据
  const imageList = ref()
  const { loading: pageLoading, runAsync: runGetImageList } = useRequest(mirrorManageApi.imageAll, {
    onSuccess: (data: any) => {
      console.log('data', data)
      imageList.value = data.data
    }
  })
  runGetImageList({ dockerPurposeType: 1 })

  const imageSelect = (val: any) => {
    mainForm.value.frame = imageList.value.find((item: any) => item.id === val)?.frame
    mainFormRef.value?.validate('frame')
  }

  /* 资源分配逻辑 -------------------------------------------------------------------------- */
  let resourceRef = ref()
  let resourceForm = ref({
    gpu: 0,
    cpuMemory: '1-2',
    cpu: 1,
    memory: 2
  })

  const resourceRules: Record<string, Rule[]> = {
    gpu: [{ required: true, message: '请选择GPU' }],
    cpuMemory: [{ required: true, message: '请选择CPU' }]
  }

  const cpuMemoryChange = (val: string | SelectValue) => {
    if (typeof val === 'string' && val.includes('-')) {
      resourceForm.value.cpu = Number(val.split('-')[0])
      resourceForm.value.memory = Number(val.split('-')[1])
    }
  }

  /* 表单提交 -------------------------------------------------------------------------- */
  const formatParams = () => {
    let mainFormData = cloneDeep(mainForm.value)
    delete mainFormData.frame
    let resourceFormData = cloneDeep(resourceForm.value)
    delete resourceFormData.cpuMemory
    let paramData = { ...mainFormData, ...resourceFormData }
    console.log('提交的数据', paramData)
    return paramData
  }
  const { loading: addLoading, runAsync: runAddAlgo } = useRequest<ResponseData<void>>(algoDevApi.saveAlgorithm)
  const { loading: updateLoading, runAsync: runEditAlgo } = useRequest<ResponseData<void>>(algoDevApi.editAlgorithm)
  const submit = async () => {
    await mainFormRef.value?.validate()
    await resourceRef.value?.validate()

    await (type.value === 'add'
      ? runAddAlgo(formatParams(), { isAddUid: true })
      : runEditAlgo({ ...formatParams(), id: algoId }, { isAddUid: true }))
    message.success('操作成功')
    router.back()
  }

  //获取详情数据

  const { loading: getDetailLoading, runAsync: runGetCaseDetail } = useRequest<ResponseData<AlgoType>>(algoDevApi.detailAlgorithm, {
    onSuccess: ({ data }) => {
      console.log('详情', data)
      Object.assign(detailData.value, data)
      for (const key in data) {
        if (Object.prototype.hasOwnProperty.call(mainForm.value, key)) {
          // @ts-ignore
          mainForm.value[key] = data[key]
        }
        if (Object.prototype.hasOwnProperty.call(resourceForm.value, key)) {
          // @ts-ignore
          resourceForm.value[key] = data[key]
        }
      }
      resourceForm.value.cpuMemory = `${data.cpu}-${data.memory}`
    }
  })
  const getDetailData = (id: string) => {
    runGetCaseDetail({}, { urlParams: { id: id } })
  }

  type.value === 'edit' && getDetailData(algoId)
</script>

<style lang="less" scoped>
  .custom-overlay-className {
    padding-bottom: 2px !important;
  }

  .tip {
    display: flex;
    align-items: center;
    margin-left: -4px;
    white-space: nowrap;
    color: rgba(25, 25, 48, 0.36);
    gap: 8px;
    cursor: default;
  }

  .w-440 {
    width: 440px;
  }

  :deep(.ant-form-item) {
    margin-bottom: 40px;

    .ant-form-item-label > label {
      width: 120px;
    }
  }

  .default-class-title {
    .font20b();

    position: relative;
    margin-bottom: 50px;

    &::before {
      position: absolute;
      top: 50%;
      left: -16px;
      width: 3px;
      height: 22px;
      background: #1868e9;
      border-radius: 0 2px 2px 0;
      content: '';
      transform: translateY(-50%);
      flex: none;
      order: 0;
      align-self: stretch;
      flex-grow: 0;
    }
  }

  .a-anchor-class {
    position: absolute !important;
    top: 54px;
    right: 10;
  }
</style>
